package com.zjun.toolkit;

import com.alibaba.fastjson2.JSON;
import com.zjun.constant.UserConstant;
import com.zjun.core.UserInfoDTO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * JWT工具类
 */
@Slf4j
public class JWTUtil {
    /**
     * jwtToken 行业标准前缀
     */
    private static final String PREFIX = "Bearer";

    /**
     * jwt密钥
     */
    private static final String SECRET = "SecretKey039245678901232039487623456783092349288901402967890140939827";

    /**
     * 签发者
     */
    private static final String ISS = "proj12306";

    /**
     * TOKEN过期时间 一天
     */
    private static final long EXPIRATION = 86400L;

    /**
     * 通过用户信息生成唯一token
     * @param userInfoDto 用户信息
     * @return 用户访问Token
     */
    public static String generateAccessToken(UserInfoDTO userInfoDto){
       Map<String, Object> customerUserMap = new HashMap<>();
       customerUserMap.put(UserConstant.USER_ID_KEY,userInfoDto.getUserId());
       customerUserMap.put(UserConstant.USER_NAME_KEY,userInfoDto.getUsername());
       customerUserMap.put(UserConstant.USER_REAL_NAME_KEY,userInfoDto.getRealName());
       String jwtToken = Jwts.builder()
               //指定签名算法和密钥
               .signWith(SignatureAlgorithm.HS512,SECRET)
               //设置签发时间,用于计算Token是否过期
               .setIssuedAt(new Date())
               //设置签发这
               .setIssuer(ISS)
               //设置主题
               .setSubject(JSON.toJSONString(userInfoDto))
               //设置过期时间
               .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
               //生成最终的JWT字符串
               .compact();
       return PREFIX+jwtToken;
   }

   public static UserInfoDTO parseJwtToken(String jwtToken){
        if (StringUtils.hasText(jwtToken)){
            String actualJwtToken = jwtToken.replace(PREFIX,"");
            try {
                Claims body = Jwts.parser().setSigningKey(SECRET).parseClaimsJwt(actualJwtToken).getBody();
                Date expiration = body.getExpiration();
                if (expiration.after(new Date())){
                    String subject = body.getSubject();
                    return JSON.parseObject(subject,UserInfoDTO.class);
                }
            }catch (ExpiredJwtException ignored){
            }catch (Exception e){
                log.error("[JWTUtil.class][JWT TOKEN解析失败]",e);
            }
        }
        return null;
    }
}
